package com.restkeeper.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.restkeeper.config.RabbitMQConfig;
import com.restkeeper.entity.EnterpiseAccount;
import com.restkeeper.exception.BussinessException;
import com.restkeeper.mapper.EnterpiseAccountMapper;
import com.restkeeper.sms.SmsObject;
import com.restkeeper.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 企业账号管理 服务实现类
 * </p>
 */
@Slf4j
@Service(version = "1.0.0", protocol = "dubbo")
public class EnterpiseAccountServiceImpl extends ServiceImpl<EnterpiseAccountMapper, EnterpiseAccount>
        implements IEnterpiseAccountService {

    @Autowired
    private AmqpTemplate rabbitmqTemplate;

    @Value("${sms.operator.signName}")
    private String signName;

    @Value("${sms.operator.templateCode}")
    private String templateCode;

    //秘钥
    @Value("${gateway.secret}")
    private String secret;

    private void sendMessage(String phone, String shopId, String pwd) {
        SmsObject smsObject = new SmsObject();
        smsObject.setPhoneNumber(phone);
        smsObject.setSignName(signName);
        smsObject.setTemplateCode(templateCode);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("shopId", shopId);
        jsonObject.put("password", pwd);
        smsObject.setTemplateJsonParam(jsonObject.toJSONString());
        rabbitmqTemplate.convertAndSend(RabbitMQConfig.ACCOUNT_QUEUE, smsObject);
    }

    @Override
    @Transactional
    public boolean add(EnterpiseAccount account) {
        boolean flag = true;
        List<EnterpiseAccount> list=this.list();
        List<String> names=list.stream().map(EnterpiseAccount::getEnterpriseName).collect(Collectors.toList());
        if(names.contains(account.getEnterpriseName())){
            throw new BussinessException("企业名称重复");
        }
        try {
            // 账号，密码特殊处理
            String shopId =getShopId();
            account.setShopId(shopId);
            //密码随机6位
            String pwd = getRandom(6);
            account.setPassword(Md5Crypt.md5Crypt(pwd.getBytes()));
            this.save(account);
            // 短信通知
            sendMessage(account.getPhone(), account.getShopId(), pwd);
        } catch (Exception ex) {
            flag = false;
            throw new BussinessException("账号添加失败"+ex.getMessage());
        }
        return flag;
    }

    /**
     * 店铺id产生规则
     * @return
     */
    private String getShopId(){
        //随机8位密码
        String shopId =getRandom(8);
        //店铺校验
        QueryWrapper<EnterpiseAccount> queryWrapper = new QueryWrapper<EnterpiseAccount>();
        queryWrapper.eq("shop_id",shopId);
        if(this.getOne(queryWrapper)!=null){
            getShopId();
        }
        return shopId;
    }

    /**
     * 密码随机数
     * @return
     */
    private String getRandom(int weight) {
        return RandomStringUtils.random(weight,
                new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 's',
                        't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9' });
    }

    @Override
    @Transactional
    public boolean resetpwd(String id, String password) {
        boolean flag=true;
        try {
            EnterpiseAccount account = this.getById(id);
            if(account==null){
                return false;
            }
            String newpwd;
            //如果设置了要重置密码
            if (!StringUtils.isEmpty(password)) {
                newpwd = password;
            } else {
                //如果没有设置要重置密码
                newpwd = getRandom(6);
            }
            account.setPassword(Md5Crypt.md5Crypt(newpwd.getBytes()));
            this.updateById(account);
            sendMessage(account.getPhone(), account.getShopId(), newpwd);
        }catch (Exception ex){
            flag =false;
            throw  ex;
        }
        return  flag;

    }

    /**
     * 支持按照企业名称模糊查询及分页支持
     *
     * @param pageNo
     * @param pageSise
     * @param name
     * @return
     */
    @Override
    public IPage<EnterpiseAccount> queryPageByName(int pageNo, int pageSise, String name) {
        IPage<EnterpiseAccount> page = new Page<EnterpiseAccount>(pageNo, pageSise);
        QueryWrapper<EnterpiseAccount> queryWrapper = new QueryWrapper<EnterpiseAccount>();
        queryWrapper.lambda().orderByDesc(EnterpiseAccount::getApplicationTime);
        if (!StringUtils.isEmpty(name)) {
            queryWrapper.lambda().like(EnterpiseAccount::getEnterpriseName, name);
        }
        return this.page(page, queryWrapper);
    }

    @Override
    public boolean recovery(String id) {
        return this.getBaseMapper().recovery(id);
    }

    @Override
    public Result login(String shopId, String telphone, String loginpass) {
        Result result = new Result();
        if (StringUtils.isEmpty(shopId)) {
            result.setStatus(ResultCode.error);
            result.setDesc("用户名为空");
            return result;
        }
        if (StringUtils.isEmpty(loginpass)) {
            result.setStatus(ResultCode.error);
            result.setDesc("密码为空");
            return result;
        }
        QueryWrapper<EnterpiseAccount> queryWrapper = new QueryWrapper<EnterpiseAccount>();
        queryWrapper.eq("phone", telphone);
        queryWrapper.eq("shop_id", shopId);
        // 未禁用状态
        //queryWrapper.notIn("status", AccountStatus.Forbidden.getStatus());
        EnterpiseAccount account = this.getOne(queryWrapper);
        if (account == null) {
            result.setStatus(ResultCode.error);
            result.setDesc("账号不存在");
            return result;
        }
        if(account.getStatus()==AccountStatus.Forbidden.getStatus()){
            result.setStatus(ResultCode.error);
            result.setDesc("账号被禁用");
            return result;
        }
        String salt = MD5CryptUtil.getSalts(account.getPassword());
        if (!Md5Crypt.md5Crypt(loginpass.getBytes(), salt).equals(account.getPassword())) {
            result.setStatus(ResultCode.error);
            result.setDesc("密码不正确");
            return result;
        }
        Map<String, Object> tokenMap = new HashMap<>();
        tokenMap.put("shopId", account.getShopId());
        tokenMap.put("loginName", account.getEnterpriseName());
        tokenMap.put("userType", SystemCode.USER_TYPE_SHOP); // 集团管理用户
        String authorization = "";
        try {
            authorization = JWTUtil.createJWTByObj(tokenMap, secret);
        } catch (IOException e) {
            log.error("加密失败", e.getMessage());
            result.setStatus(ResultCode.error);
            result.setDesc("加密失败");
            return result;
        }
        result.setStatus(ResultCode.success);
        result.setDesc("ok");
        result.setData(account);
        result.setAuthorization(authorization);
        return result;
    }
}
